package cn.jiangjiesheng.bootstrap.commons.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

@Slf4j
public class LegoPointUtil {

    public static List<Double> areaPoints(String quyuhuafenColumn) {
        List<Double> res = new ArrayList<>();
        try{
            if(!StringUtils.isEmpty(quyuhuafenColumn)){
                Object object = JSON.parse(quyuhuafenColumn);
                if (object instanceof JSONObject) {
                    JSONObject jsonObject = (JSONObject) object;
                    quyuhuafenColumn = jsonObject.getString("coords");
                }
                JSONArray pointList = JSON.parseArray(quyuhuafenColumn);
                pointList.forEach(point -> {
                    List<Double> oneP = ((JSONArray) point).toJavaList(Double.class);
                    res.addAll(oneP);
                    if(oneP.size() == 2){
                        res.add(0d);
                    }
                });
            }
        }
        catch (Exception e){
            log.error("lego区域格式解析错误", e);
        }
        return res;
    }


    public static List<Object> multiAreaPoints(String quyuhuafenColumn) {
        List<Object> res = new ArrayList<>();
        try{
            if(StringUtils.isEmpty(quyuhuafenColumn)) {
                return res;
            }
            Object object = JSON.parse(quyuhuafenColumn);
            boolean isMulti = false;
            if (object instanceof JSONObject) {
                JSONObject jsonObject = (JSONObject) object;
                quyuhuafenColumn = jsonObject.getString("coords");
                isMulti = "multiPolygon".equals(jsonObject.getString("type"));
            }
            JSONArray pointList = JSON.parseArray(quyuhuafenColumn);
            boolean fIsMulti = isMulti;
            pointList.forEach(point -> {
                if(!fIsMulti){
                    List<Double> oneP = ((JSONArray) point).toJavaList(Double.class);
                    res.addAll(oneP);
                    if(oneP.size() == 2){
                        res.add(0d);
                    }
                }
                else{
                    List<Double> onePointRes = new ArrayList<>();
                    ((JSONArray) point).forEach(onePoint -> {
                        List<Double> oneP = ((JSONArray) onePoint).toJavaList(Double.class);
                        onePointRes.addAll(oneP);
                        if(oneP.size() == 2){
                            onePointRes.add(0d);
                        }
                    });
                    res.add(onePointRes);
                }
            });
        }
        catch (Exception e){
            log.error("lego区域格式解析错误", e);
        }
        return res;
    }

    public static JSONObject pointPoints(String jinweiduColumn) {
        JSONObject res = new JSONObject();
        try{
            if(!StringUtils.isEmpty(jinweiduColumn)){
                String data = "";
                if(jinweiduColumn.indexOf("[") >= 0 && jinweiduColumn.indexOf("]") >= 0){
                    data = jinweiduColumn;
                }
                else{
                    data = "[" + jinweiduColumn + "]";
                }
                Object object = JSON.parse(data);
                if (object instanceof JSONObject) {
                    JSONObject jsonObject = (JSONObject) object;
                    data = jsonObject.getString("coords");
                }
                List<Double> oneP = JSON.parseArray(data).toJavaList(Double.class);
                res.put("lng", oneP.get(0));
                res.put("lat", oneP.get(1));
            }
        }
        catch (Exception e){
            log.error("lego区域格式解析错误", e);
        }
        return res;
    }

    public static boolean isArray(Object obj) {
        if(obj == null) {
            return false;
        }
        return obj instanceof List;
    }

    /**
     *  取几个经纬度的中心点
     */
    public static Position getCenterPoint(String quyuhuafenColumn) {
        LinkedList<Position> postionList = new LinkedList<>();
        if(!StringUtils.isEmpty(quyuhuafenColumn)){
            JSONArray pointList = JSON.parseArray(quyuhuafenColumn);
            pointList.forEach(point -> {
                List<Double> oneP = ((JSONArray) point).toJavaList(Double.class);
                postionList.add(new Position().setLatitude(oneP.get(1)).setLongitude(oneP.get(0)));
            });
        }
        else {
            return null;
        }

        if(CollectionUtils.isEmpty(postionList)){
            return null;
        }

        int total = postionList.size();
        double X = 0, Y = 0, Z = 0;

        while (!postionList.isEmpty()) {
            Position g = postionList.pollFirst();
            if (g != null) {
                double lat, lon, x, y, z;
                lat = g.getLatitude() * Math.PI / 180;
                lon = g.getLongitude() * Math.PI / 180;
                x = Math.cos(lat) * Math.cos(lon);
                y = Math.cos(lat) * Math.sin(lon);
                z = Math.sin(lat);
                X += x;
                Y += y;
                Z += z;
            }
        }

        X = X / total;
        Y = Y / total;
        Z = Z / total;
        double Lon = Math.atan2(Y, X);
        double Hyp = Math.sqrt(X * X + Y * Y);
        double Lat = Math.atan2(Z, Hyp);
        double longitude = Lon * 180 / Math.PI;
        double latitude = Lat * 180 / Math.PI;
        return new Position().setLatitude(latitude).setLongitude(longitude);
    }


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Accessors(chain = true)
    public static class Position{

        /**
         * 纬度
         */
        private Double latitude;

        /**
         * 经度
         */
        private Double longitude;

    }

}
